// rng.ixx
module; // 全局模块片段用于包含C头文件

// ================== 包含头文件 ====================
#include <project_config.h>
#include <stm32f4xx_hal.h>
// ================== 包含头文件结束 =================

export module rng;  // 声明模块接口

// 引入模块依赖
#include <cstdint>

namespace bsp::rng::detail {
    // 硬件句柄（inline确保全局唯一实例）
    inline RNG_HandleTypeDef hrng = {
        .Instance = RNG,
        .State = HAL_RNG_STATE_RESET
    };

    // 错误标志处理
    namespace flags {
        constexpr uint32_t SEIS = RNG_FLAG_SECS;  // 种子错误标志
        constexpr uint32_t CECS = RNG_FLAG_CECS;   // 时钟错误标志
    }

    // 状态检查辅助函数
    constexpr bool check_seed_error(auto& h) { return __HAL_RNG_GET_FLAG(&h, flags::SEIS); }
    constexpr bool check_clock_error(auto& h) { return __HAL_RNG_GET_FLAG(&h, flags::CECS); }
    constexpr void clear_seed_error(auto& h) { __HAL_RNG_CLEAR_FLAG(&h, flags::SEIS); }
    constexpr void clear_clock_error(auto& h) { __HAL_RNG_CLEAR_FLAG(&h, flags::CECS); }
}

export namespace bsp::rng {
    /**
     * @brief 随机数生成控制器
     * @note 封装RNG硬件操作，提供安全的随机数生成接口
     */
    class Controller {
        /**
         * @brief 检查并清除硬件错误状态
         * @details 内部自动处理种子错误和时钟错误
         */
        static void check_status() noexcept {
            using namespace detail;
            if (check_seed_error(hrng))  clear_seed_error(hrng);
            if (check_clock_error(hrng)) clear_clock_error(hrng);
        }

    public:
        /**
         * @brief 初始化硬件随机数生成器
         * @warning 需确保project_config.h已包含必要的HAL库定义
         * @exception 初始化失败时触发Error_Handler
         */
        static void init() noexcept {
            __HAL_RCC_RNG_CLK_ENABLE();
            if (HAL_RNG_Init(&detail::hrng) != HAL_OK) {
                Error_Handler();
            }
        }

        /**
         * @brief 生成32位随机数
         * @return uint32_t 成功返回有效随机数，失败返回0
         * @note 自动处理硬件错误状态，连续错误时建议重新初始化
         */
        static uint32_t generate() noexcept {
            using namespace detail;
            uint32_t value = 0;

            check_status();  // 预清理错误状态

            const auto status = HAL_RNG_GenerateRandomNumber(&hrng, &value);
            check_status();  // 生成后清理错误状态

            return (status == HAL_OK) ? value : 0;
        }

        /**
         * @brief 获取硬件状态信息
         * @retval HAL_RNG_STATE_RESET   未初始化
         * @retval HAL_RNG_STATE_READY   准备就绪
         * @retval HAL_RNG_STATE_BUSY    生成中
         * @retval HAL_RNG_STATE_ERROR   硬件错误
         */
        static auto state() noexcept {
            return detail::hrng.State;
        }
    };
}

// ================== 中断处理相关 ==================
/**
 * @brief RNG错误中断回调（需在用户代码中实现）
 * @note 若启用RNG中断需实现此回调
 */
extern "C" void HAL_RNG_ErrorCallback(RNG_HandleTypeDef* hrng) {
    // 用户在此处理RNG错误事件
}